#include <iostream>
#include <thread>
#include <shared_mutex>
#include <vector>
#include <chrono>

class ReadWriteLock {
private:
    std::shared_mutex rw_mutex;

public:
    void read_lock() {
        rw_mutex.lock_shared();
    }

    void read_unlock() {
        rw_mutex.unlock_shared();
    }

    void write_lock() {
        rw_mutex.lock();
    }

    void write_unlock() {
        rw_mutex.unlock();
    }
};

ReadWriteLock rw_lock;
int shared_data = 0;

void reader(int reader_id) {
    while (true) {
        rw_lock.read_lock();
        std::cout << "Reader " << reader_id << " reads value: " << shared_data << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Simulate read time
        rw_lock.read_unlock();
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Simulate time between reads
    }
}

void writer(int writer_id) {
    while (true) {
        rw_lock.write_lock();
        shared_data++;
        std::cout << "Writer " << writer_id << " writes value: " << shared_data << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Simulate write time
        rw_lock.write_unlock();
        std::this_thread::sleep_for(std::chrono::milliseconds(200)); // Simulate time between writes
    }
}

int main() {
    std::vector<std::thread> readers;
    std::vector<std::thread> writers;

    // Create reader threads
    for (int i = 0; i < 5; ++i) {
        readers.emplace_back(reader, i);
    }

    // Create writer threads
    for (int i = 0; i < 2; ++i) {
        writers.emplace_back(writer, i);
    }

    // Join threads
    for (auto& th : readers) {
        th.join();
    }
    for (auto& th : writers) {
        th.join();
    }

    return 0;
}
